import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
import 'package:encrypt/encrypt.dart' as Encrypt;

export 'ScreenFit.dart';
export 'Network.dart';

export '../route.dart';
export 'QGEvent.dart';
export "User.dart";
import 'dart:ui' as ui;
import "User.dart";

import 'package:permission_handler/permission_handler.dart';

bool flag = false;
setReviewState(value) {
  flag = value;
}

inReview() {
  if (!kIsWeb){ 
    return Platform.isIOS && flag;
  }else{
    return flag;
  }
}

toast(msg) async {
  EasyLoading.showToast(
    msg,
    duration: const Duration(milliseconds: 800),
    toastPosition: EasyLoadingToastPosition.bottom,
  );
}

BuildContext? ctx;
showLoading(context) {
  ctx = context;
  showDialog(
      barrierDismissible: false,
      context: context,
      builder: (context) {
        return const Center(
            child: CircularProgressIndicator(color: Colors.white));
      });
}

dismissLoading() {
  if (ctx != null) {
    Navigator.of(ctx!).pop();
    ctx = null;
  }
}

unfocus(context) {
  FocusScopeNode currentFocus = FocusScope.of(context);
  if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
    FocusManager.instance.primaryFocus?.unfocus();
  }
}

int offsetTime = 0;
updateCurrentTime(serverTime) {
  if (serverTime == null) return;
  int now = DateTime.now().millisecondsSinceEpoch;
  serverTime *= 1000;
  offsetTime = (serverTime - now);
}

getCurrentTime() {
  return DateTime.now().millisecondsSinceEpoch + offsetTime;
}

getCountdown(dynamic start) {
  if (start == null) {
    return;
  }

  if (start is String) {
    start = DateTime.parse(start).millisecondsSinceEpoch;
  }

  int now = getCurrentTime();

  if (now < start) {
    int day = 0;
    int hour = 0;
    int minute = 0;
    int second = (start - now) ~/ 1000;

    if (second > 60 * 60) {
      hour = second ~/ (60 * 60);
      second -= hour * (60 * 60);
    }
    if (second >= 60) {
      minute = second ~/ 60;
      second -= minute * 60;
    }

    String h = hour.toString().padLeft(2, '0');
    String m = minute.toString().padLeft(2, '0');
    String s = second.toString().padLeft(2, '0');
    return "$h:$m:$s";
  }
}

getCountTime(dynamic start) {
  if (start == null) {
    return;
  }

  if (start is String) {
    start = DateTime.parse(start).millisecondsSinceEpoch;
  }

  int now = getCurrentTime();

  if (now < start) {
    int day = 0;
    int hour = 0;
    int minute = 0;
    int second = (start - now) ~/ 1000;

    if (second > 24 * 60 * 60) {
      day = second ~/ (24 * 60 * 60);
      second -= day * (24 * 60 * 60);
    }
    if (second > 60 * 60) {
      hour = second ~/ (60 * 60);
      second -= hour * (60 * 60);
    }
    if (second >= 60) {
      minute = second ~/ 60;
      second -= minute * 60;
    }

    String d = day.toString().padLeft(2, '0');
    String h = hour.toString().padLeft(2, '0');
    String m = minute.toString().padLeft(2, '0');
    String s = second.toString().padLeft(2, '0');

    if (day.toInt() > 0) {
      return "$d:$h:$m:$s";
    } else {
      return "$h:$m:$s";
    }
  }
}

getTradeTime(dynamic start) {
  if (start == null) {
    return;
  }

  if (start is String) {
    start = DateTime.parse(start).millisecondsSinceEpoch;
  }

  int now = getCurrentTime();

  if (now > start) {
    int day = 0;
    int hour = 0;
    int minute = 0;
    int second = (now - start) ~/ 1000;

    if (second > 24 * 60 * 60) {
      day = second ~/ (24 * 60 * 60);
      second -= day * (24 * 60 * 60);
    }
    if (second > 60 * 60) {
      hour = second ~/ (60 * 60);
      second -= hour * (60 * 60);
    }
    if (second >= 60) {
      minute = second ~/ 60;
      second -= minute * 60;
    }

    if (day > 0) {
      return "$day天";
    }
    if (hour > 0) {
      return "$hour小时";
    }

    if (minute > 0) {
      return "$minute分钟";
    }

    if (second > 0) {
      return "$second秒";
    }
  }
}




getPurchaseNotice() {
  return """数字藏品交易仅限于18周岁(不含)以上、60周岁(含)以下，并已完成实名认证的中国大陆用户购买。由于不同属性的数字艺术有不同的二次交易规则，请您仔细阅读并同意相关规则后再进行相应操作，以避免不必要的损失。

请注意，一旦数字藏品完成出售，不支持退货在购买之前，请仔细考虑您的购买决策。根据我国相关的法律要求，特定条件下的数字藏品的二次交易不支持任何形式的变相炒作。我们坚决反对数字藏品炒作、场外交易、欺诈，以及其他非法侵权行为。请您甄别上述涉嫌网络欺诈的行为并了解相关风险。
""";
}

getAliVerifyHTML() {
  return """


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <script type="text/javascript" src="https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js"></script>
	<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

</head>
<body>
<div id="captcha-element"></div>
<button id="button"></button>
<script>

\$.when( \$.ready ).then(function(){

  let captcha;
  // 弹出式
  initAliyunCaptcha({
    SceneId: 't0y7z2e0',
    prefix: 'rf7ryo',
    mode: 'popup',
    element: '#captcha-element',
    button: '#button',
    captchaVerifyCallback: captchaVerifyCallback,
    onBizResultCallback: onBizResultCallback,
    getInstance: getInstance,
    language: 'cn',
    region: 'cn'
  });

  // 绑定验证码实例函数。该函数为固定写法，无需修改
  function getInstance(instance) {
    captcha = instance;
  }

  // 业务请求(带验证码校验)回调函数
  async function captchaVerifyCallback(captchaVerifyParam) {
    window.flutter_inappwebview.callHandler('verifyParam', captchaVerifyParam);
  }

  // 业务请求验证结果回调函数
  function onBizResultCallback(bizResult) {
    window.flutter_inappwebview.callHandler('bizResult', bizResult);
  }

});
</script>

<style>
    body{ background-color: none; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;}
    #button{ display:none; width: 0; height: 0;}
    .aliyunCaptcha-hidden{ display: block;}
    #aliyunCaptcha-mask{ display: none; opacity: 0;}
    #aliyunCaptcha-window-popup{ transform: translate(-50%, -35%) scale(3); border: none;}
    #aliyunCaptcha-btn-close{ display: none; opacity: 0;}
//     #aliyunCaptcha-window-popup{ width: 92%; top: 50%; font-size: .4rem; padding: .5rem .4rem .2rem; border: none;}
//     #aliyunCaptcha-title{ font-size: .5rem;}
//     #aliyunCaptcha-btn-close{ display: none;}
//     #aliyunCaptcha-btn-refresh, #aliyunCaptcha-btn-close{ padding: 0 .1rem; font-size: .6rem;}
//     .aliyunCaptcha-line{ margin: .5rem 0 .3rem; border: 1px solid #d3d3d3;}
//     #aliyunCaptcha-question{ padding: .2rem; font-size: .44rem;}
//     #aliyunCaptcha-img-box{ margin: .3rem 0;}
//     #aliyunCaptcha-img-box.spacesemantic, #aliyunCaptcha-img.spacesemantic{ width: 100%; height: 8rem;}
//     #aliyunCaptcha-img{ border-radius: .2rem;}
//     #aliyunCaptcha-question-box, #aliyunCaptcha-img-box{ width: 100%; border-radius: .16rem;}
//     .aliyunCaptcha-loader{ height: .9rem; width: .9rem; margin: 0 0 .2rem;}
//     .aliyunCaptcha-loading{ font-size: .5rem;}
//     .aliyunCaptcha-mark{ width: .6rem; height: .6rem; margin: 0 0 0 -0.2rem; font-size: .42rem; border: .04rem solid #fff; line-height: .52rem; box-shadow: 0 0 .1rem #000;}
</style>

</body>
</html>

""";
}

getUserAgreement() {
  return """
千格文创用户使用协议
欢迎使用平台！千格是一个允许您购买和展示数字藏品的电商平台。这些使用条款由您与千格文创（“千格文创”、“海南芊格网络科技有限公司”）签订并在您和千格文创之间订立。以下条款和条件，以及它们通过引用明确纳入的任何文件，管理您对千格文创的访问和使用，提供的任何内容、功能和服务）。
1)接受这些条款
当您使用千格文创购买或展示不可替代的数字存证（“数字藏品”）或创建数字藏品的集合（统称为“服务”）时，这些使用条款规定了您的权利和责任，所以请仔细阅读。单击“我接受”或“已同意”按钮、完成帐户注册过程或使用本平台，即表示您接受并同意受这些使用条款以及通过引用并入本文的所有条款的约束和遵守。同意这些条款，即表示您特此证明您已年满18岁。如果您不同意这些使用条款，则不得访问或使用本平台。
千格文创保留随时自行决定更改或修改这些使用条款的权利。您同意并理解，在这些使用条款发生任何更改后，通过登录您的帐户、访问或使用本平台，即表示您同意修订后的使用条款以及通过引用纳入其中的所有条款。我们鼓励您不时查看使用条款，以确保您了解访问或使用本平台时适用的条款和条件。
2)您的千格文创帐户
您需要使用千格文创创建一个帐户才能使用服务。当您创建帐户时，我们会要求您提供一些有关您自己的信息，我们可能会自行决定要求您提供其他信息和/或文件，如果您未针对此类请求提供完整准确的信息和/或文件，我们可能会拒绝向您提供服务。
您的千格文创 帐户受以下条件的约束：
· 您只能在千格文创 上开设一个帐户。如果我们有理由怀疑您在千格文创上开设了多个账户，我们保留采取我们认为适当的任何措施的权利，包括但不限于关闭和/或冻结您的账户。
· 访问：您理解并同意，对您的千格文创帐户的访问仅限于您本人。您同意，未经我们事先书面许可，您不会将您的千格文创帐户出售、出租、租赁或授予任何人访问权限。
· 安全性：您理解并同意，您全权负责维护您帐户的安全并控制您用于访问服务的任何用户名、密码或任何其他代码。第三方未经授权访问您的帐户可能会导致数字藏品和/或您帐户和任何关联帐户（包括您关联的银行帐户和银行卡）中的资金丢失或被盗。您理解并同意，您不会让我们负责管理和维护您帐户的安全。您进一步理解并同意，对于未经授权访问或使用您的帐户，我们概不负责（您也不会让我们负责）。您有责任监控您的帐户，如果您发现帐户中有任何未经授权或可疑的活动。
· 沟通：您同意并理解我们将通过电子方式与您沟通。为确保您收到我们所有的通讯，您同意保持您的电子邮件地址和电话号码为最新，并在有任何更改时通知我们。您同意发送到您记录在案的电子邮件地址的任何通知、协议、披露或其他通信均被视为有效。
3)账户暂停
如果我们自行决定怀疑 (1) 您的账户被用于洗钱或任何非法活动；(2) 您隐瞒或提供虚假身份信息或其他详细信息；(3) 您从事过欺诈活动；(4) 您以不正当的方式获得了数字藏品（包括但不限于使用被盗资金或支付方式，或在保留或处置数字藏品的同时试图退还您的款项）；(5) 您正在使用、雇用或操作机器人或其他形式的自动化和/或多个帐户来从事千格文创上的任何活动；(6) 作为平台用户您的不正当言行（包括但不限于捏造、散布虚假事实，损害他人名誉、商誉、对平台进行诋毁、造谣及传播未经证实的言论、恶意投诉）造成平台方或平台相关机构及个人遭受利益损害的；(7) 您以其他方式违反了这些使用条款；基于前述您同意千格文创有权立即暂停您的账户、暂停或取消您对服务的访问，或关闭您的账户，
如果 千格文创 有理由相信您参与了上述 (1)、(2)、(3)项活动，千格文创保留自行决定没收任何数字藏品的权利根据这些活动进行的购买和/或认为此类交易无效的权利，并且我们有权依据现行法律法规之规定采取合理合法手段维护各位用户之账户安全。
4)沟通
您同意我们可以通过电子邮件向您发送促销信息，包括但不限于时事通讯、特别优惠、调查以及我们认为您会感兴趣的其他新闻和信息。
您同意我们可以通过电子邮件或短信向您发送与千格文创上数字藏品的购买或销售状态相关的通信，以及与您与平台互动相关的其他通信，包括但不限于关于您有兴趣购买的数字藏品的状态。
5)用户内容
本平台允许 (1) 用户创建个人资料，他们可以在其中发布有关自己的某些信息、链接到其他平台并显示他们拥有的 数字藏品；(2) 数字藏品的艺术家或创作者发布他们的数字藏品和个人简介（本条（1）、（2）所述内容统称为“用户内容”）。所有用户内容都必须遵守这些使用条款。
您发布到本平台的任何个人资料信息将被视为非机密和非专有信息。通过在平台上提供任何用户内容，您授予我们和我们的附属公司以及我们各自的被许可人、继承人，并转让使用、复制、修改、执行、展示、分发、转发、发布、广播和以其他方式向第三方披露的权利任何此类材料用于任何目的。您声明并保证 ：您拥有并控制您的用户内容的所有权利，并有权向我们和我们的附属公司以及我们各自的被许可人、继承人和受让人授予此类许可；您的所有用户内容都将遵守这些使用条款。
您理解并同意您对您提交或贡献的任何用户内容负责，并且您（而非千格文创）对此类内容承担全部责任，包括其合法性、可靠性、准确性和适当性。对于您或任何其他用户在本平台上发布的任何用户内容的内容、准确性或适当性，我们不对任何第三方负责。
如果您是数字藏品的创作者者，您特此授予千格文创将您的姓名和图像用于营销或促销目的的权利；如果您是数字藏品创作者，您同意我们可以使用或修改您为营销或促销目的创建的数字藏品图像。
· 作为数字藏品创作者，您理解并同意：
· 您对数字藏品创作的准确性和内容负责；
· 任何违反千格文创政策的数字藏品可能会由千格文创自行决定混淆或删除；
· 您将尊重他人的知识产权；
· 您不会与其他数字藏品创作者协调定价。
我们保留自行决定下架您的数字藏品的权利。尽管我们不需要监控任何用户内容，但我们可以自行决定随时出于任何原因删除内容，恕不另行通知。千格文创可能会监控内容，以检测和防止欺诈活动或违反这些使用条款的行为。
6)所有权
除非我们另有书面说明，本平台、所有内容和其中包含的所有其他材料，包括但不限于千格文创徽标以及所有设计、文本、图形、图片、信息、数据、软件、声音文件、其他文件及其选择和安排（统称为“千格文创 内容”）是 千格文创（“海南芊格网络科技有限公司”）或我们的附属公司、许可方或用户（如适用）的专有财产。千格文创徽标和任何可能出现在本平台或其他地方的千格文创 产品或服务名称、徽标或标语是千格文创或我们关联公司的商标，不得全部或部分复制、模仿或使用。
未经我们明确的书面许可，您不得使用任何千格文创内容链接到本平台或内容。未经我们明确书面同意，您不得使用框架技术来封装任何千格文创内容。此外，平台和内容的外观和感觉，包括但不限于所有页面标题、自定义图形、按钮图标和脚本，构成的服务标志、商标或商业外观，不得复制、模仿、或在未经我们事先书面许可的情况下全部或部分使用。
尽管此处有任何相反的规定，您理解并同意您对您的帐户不拥有所有权或其他财产权益。
7)销售条款
在千格文创上或通过千格文创下订单，即表示您同意提交具有约束力的要约以购买此类数字藏品或服务。购买完成后，您的订单将被接受并确认，千格文创会显示确认付款页面（“确认付款页面”）。您在此明确同意在显示确认付款页面后立即开始供应数字藏品。
除法律不能排除或限制的任何法定保证或保证外，不允许退款或退货。
8)知识产权
在 千格文创 内容之外，平台上的所有其他商标、产品名称和徽标均为其各自所有者的财产，未经适用商标持有人许可，不得全部或部分复制、模仿或使用. 在不限制上述规定的情况下，如果您认为 千格文创 托管的第三方材料侵犯了您的版权或商标权，请通过以下电子邮件地址与千格文创的版权代理联系来提交侵权通知：qiangeshucang@163.com。
在这种情况下，请向千格文创的版权代理提供以下信息： (1) 授权代表版权所有者行事的人的电子或物理签名；(2) 对您声称被侵权的版权作品的描述；(3) 描述您声称侵权的材料在平台上的位置；(4) 您的地址、电话号码和电子邮件地址；(5) 您的书面声明，表明您有充分理由相信争议使用未经著作权人、其代理人或法律授权；(6) 您根据伪证罪作出的声明，声明您通知中的上述信息准确无误，并且您是版权所有者或被授权代表版权所有者行事。
千格文创的政策是暂停或终止重复侵权者的帐户。千格文创的回应可能取决于相关的加重或减轻情节，但通常我们会终止一个帐户，如果它是三个有效的侵权通知的对象。
9)您对千格文创的使用
我们特此授予您访问和使用本平台和内容的有限、非排他性、不可转让、可撤销的许可,我们授予此类许可须符合以下条件：
· 非法活动：您同意不参与或协助任何违反任何法律、法规、条例、法规或制裁计划的活动 ，或涉及任何非法活动的收益。
· 滥用活动：您同意不参与任何对千格文创构成威胁的活动，例如通过传播病毒或其他有害代码，或通过未经授权访问平台或其他用户的帐户。
· 不当行为：您同意不干扰其他用户访问或使用服务。
· 欺诈：您同意不从事任何旨在欺诈千格文创、其他用户或任何其他人的活动；或向千格文创提供任何虚假、不准确或误导性的信息。
· 赌博：您同意不利用服务参与任何彩票、竞标费拍卖、竞赛、抽奖或其他机会游戏。
· 税费：千格文创或任何其他千格文创方均不负责确定适用于您的预扣税、销售税、使用税、增值税、转让税或其他税，以及与之相关的任何利息和罚款（“税费”）。您同意，您全权负责确定适用于您的数字藏品交易的税款（如果有），并向适当的税务机关预扣、收取、报告和汇出正确的税款。
· 知识产权侵权：(1)您同意不从事涉及侵犯或违反任何版权、商标、公开权或隐私权或任何其他法律规定的专有权利的项目的交易；(2) 未经千格文创明确书面同意，使用千格文创内容；(3) 从事任何暗示对千格文创的不真实认可或从属关系的行为。
· 超链接：特此授予您有限的、非排他性的、不可转让的、可撤销的许可，以出于非商业目的创建指向本平台的文本超链接，前提是此类链接不得以虚假方式描绘千格文创、我们的附属公司或服务。误导、贬损或其他诽谤方式，并进一步规定链接站点不包含任何成人或非法材料，或其他具有攻击性、骚扰性或其他令人反感的材料。
· 附加禁令：(1)您同意不分发、出版、广播、复制、复制、转发或公开展示任何内容；(2) 您同意不修改或创建本平台或内容或其任何部分的衍生作品；(3) 您同意不在平台或内容上使用任何数据挖掘、机器人或类似的数据收集或提取方法；(4) 您同意不下载本平台或内容的任何部分，但我们明确允许的情况除外，用于页面缓存的目的除外。
如果您不确定预期的使用是否会违反这些使用条款，请通过下面联系信息下列出的地址与我们联系。
10)意外转移
您理解并同意，如果您将数字藏品存入错误地址，我们可能没有能力、也没有义务或义务将此类数字藏品退还给您。无论我们是否控制目标地址，本节都适用。
请注意：本节的例外情况可能会根据具体情况由我们自行决定。
11)隐私
您承认并同意根据 千格文创 的隐私政策收集、使用和披露您的个人信息，该政策通过引用并入本用户协议。
12)修改
您同意并理解我们可能会修改部分或全部千格文创或服务，恕不另行通知。
13)风险
请注意访问或使用千格文创的以下风险：包括数字藏品在内的区块链资产的价格和流动性极易波动，可能会出现较大波动；中国或国际层面的立法和监管变化或行动可能会对数字藏品的使用、转让、交换和价值产生不利影响；数字藏品不是法定货币；数字藏品中的交易可能是不可逆转的，因此，由于欺诈或意外交易造成的损失可能无法挽回；数字藏品中的某些交易在记录在公共分类账上时应被视为进行，这不一定是您发起交易的日期或时间；数字藏品的性质可能会导致欺诈或网络攻击的风险增加，并可能意味着遇到的技术困难可能会阻止访问或使用您的数字藏品；对第三方平台的更改（在下文第 14 节中确认）可能会产生风险，您访问和使用本平台将受到影响。
您同意并理解，您全权负责为自己确定这些风险的性质、潜在价值、适用性和适当性，并且 千格文创不会就数字藏品提供建议或建议，包括投资策略的适用性和适当性。您同意并理解访问和使用千格文创的风险由您自己承担。您同意并理解千格文创不对您在使用数字藏品时可能遇到的任何通信故障、中断、错误、扭曲或延迟负责，无论其原因是什么造成的。
14)第三方
千格文创可能依赖第三方平台，包括但不限于使用微信、支付宝等来执行数字藏品交易。我们的平台可能包含第三方平台或应用程序（统称为“第三方平台”）的链接。千格文创不拥有或控制第三方站点。您理解并同意，您对任何第三方平台的使用受该第三方平台提供的任何使用条款和/或隐私政策的约束。千格文创不是任何此类协议的一方。您应查看此类第三方平台提供的任何使用条款和/或隐私政策，并应在与任何第三方进行任何交易之前进行任何您认为必要或适当的调查。
千格文创提供这些第三方站点只是为了方便起见，不对第三方站点或其产品或服务进行审查、批准、监控、认可、保证或作出任何陈述。您使用第三方平台中的所有链接的风险由您自己承担。当您离开我们的平台时，我们的协议和政策不再适用。我们可能但没有义务，警告您正在离开我们的平台。
我们平台上的某些交易可能由第三方平台促进和运行。任何此类交易均受第三方平台服务条款和隐私政策的约束。
15)免责声明
除非千格文创以书面形式明确提供相反的规定，否则本平台、其中包含的内容和其中列出的均按“原样”和“可用”的基础提供，不附带任何保证或限制条件默示。千格文创（及其供应商）不保证本平台将 (1) 满足您的要求；(2) 在不间断、及时、安全或无错误的基础上可用；或 (3) 准确、可靠、完整、合法或安全。
对于因依赖本平台包含的材料或信息而采取或采取的任何行动而造成的任何形式的损失，我们概不负责。千格文创不声明或保证平台上的内容准确、完整、可靠、最新或无错误。
虽然 千格文创 尝试让您安全地访问和使用本平台和内容，但千格文创不能也不代表或保证本平台和内容，我们平台或我们的服务器上列出的任何数字藏品不受其他软件的限制。我们无法保证您在线披露的任何数据的安全性。您接受通过Internet 提供信息和在线交易的固有安全风险，并且不会让我们对任何安全漏洞负责，除非是由于我们的严重疏忽。
我们不对您的任何损失负责，也不对您使用数字藏品的任何用途负责，包括但不限于由以下原因引起的任何损失、损害或索赔：(1) 用户错误例如忘记密码、错误构建的交易或输入错误的地址；(2) 服务器故障或数据丢失；(3) 损坏的钱包文件；(4) 未经授权访问应用程序；(5) 任何未经授权的第三方活动，包括但不限于使用病毒、网络钓鱼、暴力破解或其他攻击平台或小工具的手段。
千格文创 不对由于漏洞或任何类型的故障、软件（例如钱包、智能合约）、区块链或数字藏品的任何其他功能的异常行为而造成的持续损失负责。千格文创不对由于开发人员或代表延迟报告支持数字藏品的区块链的任何问题（或根本没有报告）而造成的持续损失负责，包括技术节点问题或任何其他导致资金损失的问题。
没有本协议中的条款应排除或限制任何一方因疏忽、违反法律或任何其他无法通过合法手段限制或排除的活动造成的欺诈、死亡或人身伤害的责任。
在法律规定的最大范围内，千格文创特此拒绝任何形式的保证，无论是明示或暗示的、法定的或其他形式的，包括但不限于任何关于适销性和适销性的保证到站点和其中包含的内容。
上述规定不影响根据适用法律不能排除或限制的任何保证。
16)责任限制
在法律允许的最大范围内，在任何情况下，千格文创均不对您或任何第三方的任何利润损失或任何间接的、后果性的、示范性的、偶然的、特殊的或惩罚性的产品损害承担责任，或由此产生的产品损害第三方平台和产品，或与收入损失、利润损失、业务损失或预期储蓄、使用损失、商誉损失或数据丢失相关的任何损害，以及是否由侵权行为引起（包括）违反合同，或以其他方式，即使可以预见，并且即使千格文创已被告知此类损害的可能性。访问和使用平台、产品或第三方平台和产品由您自行决定并承担风险。
尽管有任何相反的规定，在任何情况下，千格文创均不承担因本协议、访问和使用本平台产品、内容或任何相关的或以任何方式与本协议相关的最大累计责任在平台上超过 (A) 100 元人民币或 (B) 您在过去六个月内为服务支付给千格文创的金额，由此产生的责任。前述责任限制不适用于责任千格文创用于 (A) 因 千格文创成员的疏忽而造成的死亡或人身伤害；或 (B) 因千格文创的欺诈或欺诈性虚假陈述的成员造成的任何伤害。
某些司法管辖区不允许排除或限制偶然或间接损害，因此上述限制或排除可能不适用于您。某些司法管辖区还限制对消费品造成的人身伤害的免责声明或责任限制，因此该限制可能不适用于人身伤害索赔。
17)赔偿
您进一步同意千格文创各方应控制任何第三方索赔的辩护或和解，此赔偿是对您与千格文创之间的书面协议中规定的任何其他赔偿的补充而非替代。
18)管辖法律
这些使用条款、您对千格文创的使用、您的权利和义务，以及由这些使用条款引起的或与之相关的所有行动均应受中国法律的管辖，就好像这些使用条款一样是在中国完全签订和完全履行的合同。您理解并同意，您按照这些使用条款的规定使用千格文创应被视为发生在中国，并受中国法律的约束，无论其是否存在法律冲突。
19)终止
我们保留随时以任何理由自行决定终止您访问或使用本平台或内容的许可的权利，恕不另行通知。您理解并同意，在这种情况下，我们对您不承担任何责任或义务。
20)可分割性
如果这些使用条款的任何条款或规定无效或不可执行，则该条款或规定应与这些使用条款分开，并且不会影响该条款任何剩余部分的有效性或可执行性。
这些使用条款构成您与千格文创之间关于您访问和使用平台和内容的完整协议，并取代任何和所有先前的讨论协议以及任何类型的理解（包括但不限于本用户协议的先前版本）。除非本文另有规定，否则这些使用条款仅旨在为各方谋取利益，无意将第三方受益权授予任何其他人或实体。
21)联系方式
如果您有任何问题、想提供反馈或想了解有关 千格文创 的更多信息，请随时发送电子邮件至 qiangeshucang@163.com。如果您想提出投诉，请通过qiangeshucang@163.com与我们联系。
""";
}

getPrivacyPolicy() {
  return """
千格文创隐私政策
千格文创（“公司”、“平台”或“我们”）致力于保护您的隐私。我们准备了本隐私政策，在线服务（“服务”）的网站用户那里收集的个人数据（定义见下文）的做法。
1.联系公司
如果您对我们的隐私政策或我们的数据收集或处理做法有任何问题、疑虑或投诉，或者您想向我们报告任何安全违规行为，请通过以下电子邮件地址与我们联系：qiangeshucang@163.com。
2.用户同意
通过我们的网站或服务提交个人数据，即表示您同意本隐私政策的条款，并且您明确同意根据本隐私政策收集、使用和披露您的个人数据。为了进行数字作品交易，允许我们使用第三方支付平台。
3.关于儿童的说明
我们不会故意从18岁以下的访问者那里收集个人数据，如果18岁以下的未成年人向公司提交个人数据，并且我们了解到个人数据是18岁以下未成年人的信息，我们将尝试尽早删除该信息。如果您认为我们可能拥有18岁以下未成年人的任何个人数据，请通过第 (1) 段中指定的地址与我们联系。
4.中国境外用户须知
如果您是本网站的非中国用户，通过访问本网站并向我们提供数据，您承认并同意您的个人数据可能会被处理用于隐私政策中确定的目的。此外，您的个人数据可能会在收集数据的国家和其他国家/地区（包括中国）进行处理，在这些国家/地区，有关个人数据处理的法律可能不如您所在国家/地区的法律严格。提供您的数据，即表示您同意此类传输。
5.我们收集的数据类型
“个人数据”是指允许某人识别或与您联系的数据，包括例如您的姓名、地址、电话号码、电子邮件地址，以及与您相关联或链接的任何其他非公开信息任何上述数据。“匿名数据”是指与您的个人数据无关或链接的数据，包括汇总和去标识化数据；匿名数据本身不允许识别个人。我们收集个人数据和匿名数据，如下所述一种，您提供给我们的信息。
▪ 当您创建一个帐户以登录我们的网络（“帐户”）时，我们可能会收集您的个人数据，例如您的姓名、电子邮件和邮寄地址以及密码。
▪ 如果您在移动设备上使用我们的服务，我们可能会收集您的电话号码和唯一的设备 ID 号码。
▪ 我们的站点允许您存储偏好，例如您的内容的显示方式、您的位置、安全搜索设置和最喜欢的小部件。我们可能会将这些选择与您的 ID、浏览器或移动设备相关联，您可以随时编辑这些首选项。
▪ 当通过唯一标识您的移动设备的服务提供商连接到我们的服务时，我们可能会收到此标识并使用它来提供扩展服务和/或功能。
▪ 某些服务，例如两步验证，可能需要我们收集您的电话号码。我们可能会将该电话号码与您的移动设备识别信息相关联。
▪ 如果您向我们提供反馈或通过电子邮件与我们联系，我们将收集您的姓名和电子邮件地址，以及电子邮件中包含的任何其他内容，以便向您发送回复。
▪ 我们还会收集您自愿提供给我们的其他类型的个人数据，例如您的操作系统和版本、产品注册号，以及如果您通过电子邮件与我们联系以获取服务支持所需的其他信息。
▪ 我们也可能会在我们网站的其他表明正在收集个人数据或通过技术收集的信息。当您浏览我们的网站并与之互动时，我们可能会使用自动数据收集技术来收集有关您的设备、浏览行为和模式的某些信息，包括：
▪ 为了使我们的网站和服务对您更有用，我们的服务器（可能由第三方服务提供商托管）从您那里收集信息，包括您的浏览器类型、操作系统、互联网协议（“IP”）地址（当您使用互联网时自动分配给您的计算机的数字） ，这可能因会话而异）、域名和/或您访问的日期/时间戳。
▪ 与大多数网站一样，我们会自动收集某些信息并将其存储在日志文件中。此信息包括 IP 地址、浏览器类型、互联网服务提供商 (“ISP”)、引用/退出页面、操作系统、日期/时间戳和点击流数据。我们使用这些信息来分析趋势、管理网站、跟踪用户在网站上的活动、收集关于我们整个用户群的人口统计信息，并更好地根据用户的需求定制我们的服务。例如，可能会收集某些信息，以便当您再次访问本网站或服务时，它会识别您，然后这些信息可用于提供适合您兴趣的广告和其他信息。
▪ 像许多在线服务一样，我们使用 cookie 来收集信息。“Cookies”是网站在您浏览网站时发送到您计算机硬盘的小块信息。我们可能会同时使用会话 Cookie（一旦您关闭您的网络浏览器就会过期）和持久性 Cookie（在您将其删除之前会一直保留在您的计算机上），以便在我们的网站上为您提供更加个性化和互动的体验。收集此类信息是为了使本网站对您更有用，并定制我们的体验以满足您的特殊兴趣和需求。
▪ 此外，我们使用“像素标签”（也称为清晰的 Gif、网络信标或网络错误）。像素标签是具有唯一标识符的微小图形图像，其功能类似于 Cookie，用于跟踪 Web 用户的在线活动。与存储在用户计算机硬盘驱动器上的 Cookie 相比，像素标签以隐形方式嵌入在网页中。像素标签还允许我们以用户可以阅读的格式发送电子邮件消息，它们会告诉我们电子邮件是否已打开，以确保我们只发送用户感兴趣的消息。我们可能会使用这些信息来减少或消除发送给用户的消息。我们不会将 Pixel Tags 收集的信息与我们用户的个人数据联系起来。
▪ 我们目前不响应“不跟踪”信号或其他可能使用户选择退出我们网站跟踪的机制。
▪ 快速 LSO，当我们发布视频时，第三方可能会使用本地共享对象（称为“Flash Cookie”）来存储您对音量控制的偏好或对某些视频功能进行个性化设置。Flash Cookie 与浏览器 Cookie 不同，因为数据的数量和类型以及数据的存储方式。您的浏览器提供的 Cookie 管理工具不会删除 Flash Cookie。
▪ 除了我们放置的跟踪技术外，其他公司可能会在您访问我们的网站时设置他们自己的 Cookie 或类似工具。这包括第三方分析服务，包括但不限于谷歌分析（“分析服务”），我们参与帮助分析用户如何使用网站。我们可能会收到基于这些方单独或汇总使用这些工具的报告。我们仅使用从分析服务获得的信息来改进我们的网站和服务。由 Cookie 或其他技术生成的有关您使用我们网站和服务的信息（“分析信息”）将传输到分析服务。分析服务使用分析信息来编制用户活动报告。分析服务也可能在法律要求的情况下将信息传输给第三方，或者此类第三方代表他们处理分析信息。每个分析服务使用和共享分析信息的能力受到此类分析服务的使用条款和隐私政策的限制。使用我们的网站和服务，即表示您同意分析服务以上述方式和目的处理有关您的数据。如需分析服务的完整列表，请通过第 (1) 段中提供的地址与我们联系。从您那里收集的关于他人的信息，从第三方公司收集的信息，我们可能会从通过联合品牌或自有品牌网站提供我们服务的公司或在我们的网站上提供其产品和/或服务的公司接收有关您的个人和/或匿名数据。这些第三方公司可能会向我们提供个人数据。我们可能会将此添加到我们已经通过我们的网站从您那里收集的信息中，以改进我们提供的服务。我们不会自动收集个人数据，但我们可能会将我们自动收集的信息与我们从其他来源收集的或您提供给我们的有关您的个人数据联系起来。
6.使用您的个人数据 一般使用
一般而言，您提交给我们的个人数据用于回应您提出的请求，或帮助我们更好地为您服务。我们通过以下方式使用您的个人数据：
▪ 促进在我们的网络上创建和保护您的帐户；
▪ 在我们的系统中将您识别为用户；
▪ 改进对我们网站和服务的管理；
▪ 提供您请求的服务，包括但不限于通过微信、支付宝等促进您的数字作品交易；
▪ 提高您与我们的网站和服务互动时的体验质量；
▪ 向您发送短信，以验证您在创建帐户时提供的手机号码所有权；
▪ 保护您和其他用户免受任何违反使用条款的行为或防止滥用或骚扰任何用户的行为；
▪ 在您网站上出售的数字作品旁边显示您的用户名；
▪ 向您发送管理短信通知，例如安全或支持和维护建议；
▪ 回应您对就业机会或其他要求的询问；
▪ 不时给您打电话，作为欺诈保护的一部分或征求您的反馈意见；
▪ 以我们在您提供个人数据时可能描述的任何其他方式；
▪ 发送与我们的服务和公司其他营销目的相关的时事通讯、调查、优惠和其他宣传材料。
我们可能会使用您的个人数据就您可能感兴趣的我们自己和第三方的商品和服务与您联系。创建匿名数据，我们可能会通过排除使数据可识别您个人身份的信息（例如您的姓名）来从个人数据创建匿名数据记录。我们使用这些匿名数据来分析请求和使用模式，以便我们可以增强我们服务的内容并改进站点导航。我们保留出于任何目的使用匿名数据并不受限制地向第三方披露匿名数据的权利。
7.披露您的个人数据
我们会按照下文所述以及本隐私政策其他地方的说明披露您的个人数据。一种，第三方服务提供商，我们可能会与第三方服务提供商共享您的个人数据，向您提供我们通过我们的网站向您提供的服务；进行质量保证测试；促进帐户的创建；提供技术支持；或向本公司提供其他服务。附属公司，我们可能会与我们的母公司、子公司、合资企业或其他受共同控制的公司（“关联公司”）共享您的部分或全部个人数据，在这种情况下，我们将要求我们的关联公司遵守本隐私政策。企业重组，我们可能会在与任何合并、融资、收购或解散交易或涉及出售、转让、剥离或披露我们全部或部分业务或资产的程序。在资不抵债、破产或接管的情况下，个人数据也可能作为商业资产转移。如果另一家公司收购了我们的公司、业务或资产，则该公司将拥有我们收集的个人数据，并将承担本隐私政策中所述的与您的个人数据相关的权利和义务。根据法律要求，无论您对您的个人数据做出任何选择（如下所述），如果公司真诚地认为此类披露是必要的，则公司可能会披露个人数据 (a) 与任何法律调查有关；(b) 遵守相关法律或回应送达给公司的传票或认股权证；(c) 保护或捍卫公司或网站或服务用户的权利或财产； (d) 调查或协助防止任何违反或可能违反法律、本隐私政策或我们的使用条款的行为。e. 其他披露。我们也可能会披露您的个人数据，以实现您提供的目的，用于我们在您提供时披露的任何其他目的或征得您的同意。
8.第三方网站
我们的网站可能包含第三方网站的链接，当您点击任何其他网站或位置的链接时，您将离开我们的网站并前往另一个网站，另一个实体可能会从您那里收集个人数据或匿名数据。我们无法控制、不审查这些外部网站或其内容，也不对其负责。请注意，本隐私政策的条款不适用于这些外部网站或内容，也不适用于您点击此类外部网站的链接后对您个人数据的任何收集。我们鼓励您阅读您访问的每个网站的隐私政策。第三方网站或位置的链接是为了您的方便，并不表示我们对此类第三方或其产品、内容或网站的认可。
9.您对信息的选择
关于使用我们服务的信息，您有多种选择：电子邮件通讯，我们会定期向您发送免费时事通讯和电子邮件，直接宣传我们网站或服务的使用。当您收到我们的时事通讯或促销通讯时，您可以表明偏好停止接收我们的进一步通讯，并且您将有机会按照您收到的电子邮件中提供的退订说明或联系直接联系我们（请参阅下面的联系信息）。尽管您指定了电子邮件偏好，我们仍可能向您发送与服务相关的通信，包括我们的使用条款或隐私政策的任何更新通知。 如果您在任何时候决定不再出于上述任何目的从我们的服务中接受 Cookie，那么您可以通过更改其设置来指示您的浏览器停止接受 Cookie 或在接受来自我们服务的 Cookie 之前提示您您访问的网站。查阅浏览器的技术信息。但是，如果您不接受 Cookie，您可能无法使用服务的所有部分或服务的所有功能。如果您对如何禁用或修改 Cookie 有任何疑问，请通过下面提供的联系信息告诉我们。更改或删除您的个人数据，所有用户都可以通过联系我们或通过服务编辑他们的个人资料来查看、更新、更正或删除用户在其用户帐户（包括任何导入的联系人）中提供的个人数据。如果您完全删除所有个人数据，则您的用户帐户可能会被停用。我们将尽商业上合理的努力来满足您的要求。我们可能会根据法律要求或出于合法商业目的保留您的记录的存档副本。
10.本隐私政策的变更
本隐私政策可能因任何原因不时更新，我们将通过发布新的隐私政策来通知您隐私政策的任何更改。在本隐私政策的开头标明了隐私政策的最后修订日期。您有责任确保我们为您提供最新的有效且可交付的电子邮件地址，并定期访问我们的网站和本隐私政策以检查任何更改。
11.您授权我们收集并与我们的支付提供商共享您的个人信息，包括全名、电子邮件地址和财务信息，并且您对该数据的准确性和完整性负责。
""";
}

getInviteCode(int uid, {int len = 4}) {
  var charset = [];
  for (int i = 0; i < 10; i++) {
    charset.add("$i");
  }
  for (int i = 97; i < 97 + 26; i++) {
    charset.add(String.fromCharCode(i));
  }
  for (int i = 65; i < 65 + 26; i++) {
    charset.add(String.fromCharCode(i));
  }

  int num = int.parse("$uid");

  var code = "";
  for (var i = 0; i < len; i++) {
    var idx = num % charset.length;
    code = charset[idx] + code;
    num = num ~/ charset.length;
  }

  return code;
}


Future<ui.Image> loadImageData(url) async {
  ImageProvider provider = CachedNetworkImageProvider(url);

  Completer<ui.Image> completer = Completer<ui.Image>(); //完成的回调
  ImageStreamListener? listener;
  ImageStream stream = provider.resolve(ImageConfiguration.empty); //获取图片流
  listener = ImageStreamListener((ImageInfo frame, bool sync) {
    final ui.Image image = frame.image;
    completer.complete(image); //完成
    stream.removeListener(listener!); //移除监听
  });
  stream.addListener(listener); //添加监听
  return completer.future; //返回
}

 

 

saveImage(url) async {
  if (!kIsWeb) {
 if (Platform.isIOS) {
    if (!await Permission.photos.status.isGranted) {
      await Permission.photos.request();
    }
  } else if (Platform.isAndroid) {
    if (!await Permission.storage.status.isGranted) {
      await Permission.storage.request();
    }
  }
  }
 

  var img = await loadImageData(url);
  var byteData = await img.toByteData(format: ui.ImageByteFormat.png);

  var uint8List = byteData?.buffer.asUint8List();

  dynamic ret = await ImageGallerySaverPlus.saveImage(uint8List!);

  if (ret is Map && ret["isSuccess"]) {
    toast("保存成功");
  } else {
    toast("保存失败,请检查相册权限");
  }
}

getshortAddress(addr) {
  if (addr is String && addr.length >= 42) {
    return "${addr.substring(0, 5)} ***** ${addr.substring(addr.length - 5, addr.length)}";
  }
  return "$addr";
}

decrypt(String encoded) {
  var bytes = utf8.encode("8d0253a5e7d9c47887799800566543");
  bytes = Uint8List.fromList(sha1.convert(bytes).bytes);
  bytes = Uint8List.fromList(sha1.convert(bytes).bytes);
  bytes = bytes.sublist(0, 16);

  var b64 = base64Encode(bytes);
  var key = Encrypt.Key.fromBase64(b64);
  var iv = Encrypt.IV.fromBase64(b64);
  var aes = Encrypt.AES(key, mode: Encrypt.AESMode.ecb);

  try {
    encoded = String.fromCharCodes(base64Decode(encoded).toList());
    return Encrypt.Encrypter(aes).decrypt16(encoded, iv: iv);
  } catch (e) {
    return encoded;
  }
}

encrypt(String source) {
  var bytes = utf8.encode("8d0253a5e7d9c47887799800566543");
  bytes = Uint8List.fromList(sha1.convert(bytes).bytes);
  bytes = Uint8List.fromList(sha1.convert(bytes).bytes);
  bytes = bytes.sublist(0, 16);

  var b64 = base64Encode(bytes);
  var key = Encrypt.Key.fromBase64(b64);
  // var iv = Encrypt.IV.fromBase64(b64);
  var aes = Encrypt.AES(key, mode: Encrypt.AESMode.ecb);

  try {
    return Encrypt.Encrypter(aes).encrypt(source).base16;

    // encoded = String.fromCharCodes(base64Decode(encoded).toList());
    // return Encrypt.Encrypter(aes).decrypt16(encoded, iv: iv);
  } catch (e) {
    return source;
  }
}

decryptToJson(String encoded) {
  try {
    return jsonDecode(decrypt(encoded));
  } catch (e) {
    return encoded;
  }
}

getSign(DateTime now) {
  var y = now.year.toString();
  var M = now.month.toString().padLeft(2, "0");
  var d = now.day.toString().padLeft(2, "0");
  var h = now.hour.toString().padLeft(2, "0");
  var m = now.minute.toString().padLeft(2, "0");
  var s = now.second.toString().padLeft(2, "0");

  return md5.convert(const Utf8Encoder().convert("$d$M$y$m$h$s")).toString();
}

getTSig(timestamp) {
  var token = User.current?.token ?? "";
  if (token.isEmpty) {
    return "";
  }

  var ts = "$timestamp";
  var start = ts.substring(ts.length - 4, ts.length);
  var end = ts.substring(0, 6);

  var str = encrypt("$start$token$end");
  str = base64Encode(utf8.encode(str));
  return str;
}
